package com.xyz.update

import android.text.TextUtils
import com.xyz.update.bean.Base
import com.xyz.update.bean.BaseMapToBody
import com.xyz.update.bean.VersionInfo
import com.xyz.update.bean.VersionInfoV2
import com.xyz.update.net.apiService
import com.xyz.update.update.XyToastUtils
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.net.URL

class UpdateUtils private constructor() {

    companion object {

        @JvmStatic
        @Synchronized
        fun getInstance(): UpdateUtils {
            return UpdateUtils()
        }
    }

    /**
     * 检查应用更新V3
     * @param url 请求地址
     * @param versionNum 当前版本号
     * @param callback 回调
     */
    fun checkIsUpdateV3(
        appUrl: String, appProjectCode: String, token: String,
        deviceId: String, versionNum: String?, callback: (versionInfo: VersionInfo?) -> Unit
    ) {
        try {
            val body = mapOf(
                "data" to mapOf(
                    "version" to versionNum,
                    "sysType" to "android",
                    "appProjectCode" to appProjectCode
                )
            )
            val url = URL(appUrl)
            apiService("${url.protocol}://${url.host}")
                .versionIsUpdateV2(appUrl, BaseMapToBody.convertMapToBody(body), token, deviceId)
                .enqueue(object : Callback<Base<VersionInfoV2>> {
                    override fun onResponse(
                        call: Call<Base<VersionInfoV2>>,
                        response: Response<Base<VersionInfoV2>>
                    ) {
                        try {
                            if (response.body() != null) {
                                response.body()?.let {
                                    val bean = response.body()?.data?.let {
                                        val versionInfo = VersionInfo()
                                        versionInfo.appVersion = it.lastVersion
                                        versionInfo.isCoerceUpdate = it.isNeedUpdate
                                        versionInfo.describe = it.content
                                        versionInfo.fileUrl = it.fileUrl
                                        versionInfo.isUpdate = versionNum != it.lastVersion
                                        versionInfo
                                    }
                                    callback.invoke(bean)
                                }
                            } else {
                                val string = response.errorBody()?.string()
                                if (!string.isNullOrEmpty()) {
                                    val json = JSONObject(string)
                                    XyToastUtils.showShort(json.getString("message"))
                                }
                                callback.invoke(null)
                            }
                        } catch (e: Exception) {
                            e.printStackTrace()
                            callback.invoke(null)
                        }
                    }

                    override fun onFailure(call: Call<Base<VersionInfoV2>>, t: Throwable) {
                        t.printStackTrace()
                        callback.invoke(null)
                    }
                })
        } catch (e: Exception) {
            e.printStackTrace()
            callback.invoke(null)
        }
    }

    /**
     * 检查应用更新V2
     * @param url 请求地址
     * @param versionNum 当前版本号
     * @param callback 回调
     */
    fun checkIsUpdateV2(
        appUrl: String, versionNum: String?, callback: (versionInfo: VersionInfo?) -> Unit
    ) {
        try {
            val body = mapOf(
                "data" to mapOf(
                    "version" to versionNum,
                    "sysType" to "android"
                )
            )
            val url = URL(appUrl)
            apiService("${url.protocol}://${url.host}")
                .versionIsUpdateV2(appUrl, BaseMapToBody.convertMapToBody(body))
                .enqueue(object : Callback<Base<VersionInfoV2>> {
                    override fun onResponse(
                        call: Call<Base<VersionInfoV2>>,
                        response: Response<Base<VersionInfoV2>>
                    ) {
                        try {
                            if (response.body() != null) {
                                response.body()?.let {
                                    val bean = response.body()?.data?.let {
                                        val versionInfo = VersionInfo()
                                        versionInfo.appVersion = it.lastVersion
                                        versionInfo.isCoerceUpdate = it.isNeedUpdate
                                        versionInfo.describe = it.content
                                        versionInfo.fileUrl = it.fileUrl
                                        versionInfo.isUpdate = versionNum != it.lastVersion
                                        versionInfo
                                    }
                                    callback.invoke(bean)
                                }
                            } else {
                                val string = response.errorBody()?.string()
                                if (!string.isNullOrEmpty()) {
                                    val json = JSONObject(string)
                                    XyToastUtils.showShort(json.getString("message"))
                                }
                                callback.invoke(null)
                            }
                        } catch (e: Exception) {
                            e.printStackTrace()
                            callback.invoke(null)
                        }
                    }

                    override fun onFailure(call: Call<Base<VersionInfoV2>>, t: Throwable) {
                        t.printStackTrace()
                        callback.invoke(null)
                    }
                })
        } catch (e: Exception) {
            e.printStackTrace()
            callback.invoke(null)
        }
    }

    /**
     * 检查应用更新
     * @param hostUrl 域名
     * @param versionNum 当前版本号
     * @param callback 回调
     */
    fun checkIsUpdate(
        hostUrl: String, versionNum: String?, moduleId: String,
        callback: (versionInfo: VersionInfo?) -> Unit
    ) {
        try {
            apiService(hostUrl).versionIsUpdate(1, versionNum, 1, moduleId)
                .enqueue(object : Callback<Base<VersionInfo>> {
                    override fun onResponse(
                        call: Call<Base<VersionInfo>>,
                        response: Response<Base<VersionInfo>>
                    ) {
                        try {
                            if (response.body() != null) {
                                response.body()?.let {
                                    callback.invoke(response.body()?.data)
                                }
                            } else {
                                val string = response.errorBody()?.string()
                                if (!string.isNullOrEmpty()) {
                                    val json = JSONObject(string)
                                    XyToastUtils.showShort(json.getString("message"))
                                }
                                callback.invoke(null)
                            }
                        } catch (e: Exception) {
                            e.printStackTrace()
                            callback.invoke(null)
                        }
                    }

                    override fun onFailure(call: Call<Base<VersionInfo>>, t: Throwable) {
                        t.printStackTrace()
                        callback.invoke(null)
                    }
                })
        } catch (e: Exception) {
            e.printStackTrace()
            callback.invoke(null)
        }
    }

    /**
     * 获取apk下载地址
     * @param hostUrl 域名
     * @param versionNum 当前版本号
     * @param callback 回调
     */
    fun getDownloadUrl(
        hostUrl: String, versionNum: String?, moduleId: String,
        callback: (downloadUrl: String?) -> Unit
    ) {
        try {
            apiService(hostUrl).getFileResourcesUrl(1, versionNum, 1, moduleId)
                .enqueue(object : Callback<Base<String>> {
                    override fun onResponse(
                        call: Call<Base<String>>,
                        response: Response<Base<String>>
                    ) {
                        try {
                            if (response.body() != null) {
                                response.body()?.let {
                                    if (TextUtils.isEmpty(it.fileDomain) || TextUtils.isEmpty(it.data)) {
                                        callback.invoke(null)
                                    } else {
                                        callback.invoke(it.fileDomain + it.data)
                                    }
                                }
                            } else {
                                val string = response.errorBody()?.string()
                                if (!string.isNullOrEmpty()) {
                                    val json = JSONObject(string)
                                    XyToastUtils.showShort(json.getString("message"))
                                }
                                callback.invoke(null)
                            }
                        } catch (e: Exception) {
                            e.printStackTrace()
                            callback.invoke(null)
                        }
                    }

                    override fun onFailure(call: Call<Base<String>>, t: Throwable) {
                        t.printStackTrace()
                        callback.invoke(null)
                    }
                })
        } catch (e: Exception) {
            e.printStackTrace()
            callback.invoke(null)
        }
    }
}